////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

#ifndef __WN_CONTAINERS_SINGLETON_H__
#define __WN_CONTAINERS_SINGLETON_H__

#include "WNCore/inc/WNTypes.h"
#include "WNConcurrency/inc/WNCallOnce.h"

namespace WNContainers {
    template <typename Type>
    class WNSingleton {
    public:
        static WN_VOID Initialize();
        static WN_VOID Destroy(); // Not thread safe

        static Type* GetInstancePointer();
        static Type& GetInstanceReference();

    protected:
        WNSingleton() {}
        virtual ~WNSingleton() {}

    protected:
        static Type* mInstance;

    private:
        WNSingleton(const WNSingleton&) {}
        WN_VOID operator = (const WNSingleton&) {}

        static WN_VOID CreateInstance();

    private:
        static WNOnceFlag mOnce;
    };
}

#include "WNContainers/inc/WNSingleton.inl"

#endif // __WN_CONTAINERS_SINGLETON_H__